<?php
namespace app\common\service;

use app\dto\R;
use think\facade\Config;
use think\facade\Cache;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

/**
 * 邮件服务类
 */
class EmailService
{
    /**
     * 验证码缓存前缀
     */
    private const CACHE_PREFIX = 'email_verification_';
    
    /**
     * 验证码有效期（秒）
     */
    private const CODE_EXPIRE_TIME = 300; // 5分钟
    
    /**
     * 验证码长度
     */
    private const CODE_LENGTH = 6;
    
    /**
     * 发送验证码邮件
     *
     * @param string $email 接收邮箱
     * @param string $subject 邮件主题
     * @return array R联调对象 ['code' => 0, 'msg' => '发送成功'] 或 ['code' => 1, 'msg' => '错误信息']
     */
    public function sendVerificationEmail($email, $subject = 'Uni商城的注册')
    {
        try {
            // 生成验证码
            $code = $this->generateCode();
         
            // 存储验证码
            $this->saveVerificationCode($email, $code);
            
            // 邮件内容
            $body = $this->getEmailTemplate($code);
            
            // 发送邮件
            $result = $this->sendEmail($email, $subject, $body);
            
            if ($result === true) {
                return R::codeSent();
            } else {
                return R::error("发送失败: " . $result);
            }
        } catch (\Exception $e) {
            halt($e->getMessage());
            return R::codeError();
        }
    }
    
    /**
     * 验证邮箱验证码
     *
     * @param string $email 邮箱
     * @param string $code 验证码
     * @return bool 验证结果
     */
    public function verifyCode($email, $code)
    {
        // 从缓存中获取验证码
        $cacheKey = self::CACHE_PREFIX . $email;
        $savedCode = Cache::get($cacheKey);
        
        // 用于调试的输出
        // echo "当前验证码：{$code} (" . gettype($code) . ")\n";
        // echo "当前邮箱：{$email}\n";
        // echo "缓存中的验证码：" . ($savedCode ?: "无") . " (" . gettype($savedCode) . ")\n";
        
        // 确保类型一致（转换为字符串）
        $code = (string)$code;
        $savedCode = (string)$savedCode;
        
        // 去除可能的空白字符
        $code = trim($code);
        $savedCode = trim($savedCode);
        
        // 验证码匹配检查 - 使用宽松比较
        if ($savedCode && $savedCode == $code) {
            // 验证成功后删除验证码
            Cache::delete($cacheKey);
            return true;
        }
        
        return false;
    }
    
    /**
     * 生成随机验证码
     *
     * @return string
     */
    private function generateCode()
    {
        return str_pad(mt_rand(0, pow(10, self::CODE_LENGTH) - 1), self::CODE_LENGTH, '0', STR_PAD_LEFT);
    }
    
    /**
     * 保存验证码到缓存
     *
     * @param string $email 邮箱
     * @param string $code 验证码
     */
    private function saveVerificationCode($email, $code)
    {   
        $cacheKey = self::CACHE_PREFIX . $email;
        Cache::set($cacheKey, $code, self::CODE_EXPIRE_TIME);
    }
    
    /**
     * 获取邮件模板
     *
     * @param string $code 验证码
     * @return string
     */
    private function getEmailTemplate($code)
    {
        $template = '<!DOCTYPE html>';
        $template .= '<html>';
        $template .= '<head>';
        $template .= '<meta charset="UTF-8">';
        $template .= '<title>Uni商城的注册</title>';
        $template .= '<style>';
        $template .= '.container { width: 600px; margin: 0 auto; padding: 20px; font-family: Arial, sans-serif; }';
        $template .= '.header { background-color: #4CAF50; color: white; padding: 10px; text-align: center; }';
        $template .= '.content { padding: 20px; line-height: 1.6; }';
        $template .= '.code { font-size: 24px; font-weight: bold; color: #4CAF50; text-align: center; padding: 10px; margin: 20px 0; background-color: #f5f5f5; border-radius: 5px; }';
        $template .= '.footer { font-size: 12px; color: #888; text-align: center; margin-top: 20px; }';
        $template .= '</style>';
        $template .= '</head>';
        $template .= '<body>';
        $template .= '<div class="container">';
        $template .= '<div class="header"><h2>Uni商城 - 邮箱验证</h2></div>';
        $template .= '<div class="content">';
        $template .= '<p>尊敬的用户：</p>';
        $template .= '<p>您好！感谢您注册Uni商城。请使用以下验证码完成邮箱验证：</p>';
        $template .= '<div class="code">' . $code . '</div>';
        $template .= '<p>该验证码将在5分钟内有效，请尽快完成验证。</p>';
        $template .= '<p>如果您没有进行此操作，请忽略此邮件。</p>';
        $template .= '<p>祝您购物愉快！</p>';
        $template .= '<p>Uni商城团队</p>';
        $template .= '</div>';
        $template .= '<div class="footer">';
        $template .= '<p>此邮件为系统自动发送，请勿直接回复。</p>';
        $template .= '<p>© 2025 Uni商城，保留所有权利。</p>';
        $template .= '</div>';
        $template .= '</div>';
        $template .= '</body>';
        $template .= '</html>';
        
        return $template;
    }
    
    /**
     * 发送邮件的实际方法
     *
     * @param string $to 收件人
     * @param string $subject 主题
     * @param string $body 内容
     * @return bool|string 成功返回true，失败返回错误信息
     */
    private function sendEmail($to, $subject, $body)
    {
        // 获取邮件配置
        $config = Config::get('mail');
        
        // 初始化PHPMailer
        $mail = new PHPMailer(true);
        
        try {
            // 服务器设置
            $mail->SMTPDebug = 1;                      // 启用详细调试输出
            $mail->isSMTP();                           // 使用SMTP
            $mail->Host = $config['host'];             // SMTP服务器
            $mail->SMTPAuth = true;                    // 启用SMTP认证
            $mail->Username = $config['username'];     // SMTP用户名
            $mail->Password = $config['password'];     // SMTP密码
            $mail->SMTPSecure = $config['secure'];     // 启用TLS加密，也可以是'ssl'
            $mail->Port = $config['port'];             // TCP端口
            $mail->CharSet = 'UTF-8';                  // 设置字符集
            
            // 发件人
            $mail->setFrom($config['from_email'], $config['from_name']);
            
            // 收件人
            $mail->addAddress($to);
            
            // 内容
            $mail->isHTML(true);                       // 设置邮件格式为HTML
            $mail->Subject = $subject;
            $mail->Body = $body;
            
            // 发送邮件
            $mail->send();
            return true;
        } catch (Exception $e) {
            return $mail->ErrorInfo;
        }
    }
}